为什么如此安全的https协议却仍然可以被抓包呢?
上一篇原创写了一篇关于抓包的文章,教大家如何在Android手机上对https协议的请求进行抓包。
https协议是一种非常安全的数据传输协议,它在网络上传输的所有内容都是经过加密的。这可能也让一些小伙伴非常不解,如此安全的https协议为什么也能被抓包?这样不就说明这个协议也并不安全吗?
其实并不是如此。https协议确实是非常安全的,但同时,用https协议传输的数据也确实是可以被抓包的,它们两者之间并不冲突。
那么今天,我们就来探究一下,为什么说它们两者之间并不冲突,以及市场上那些主流的抓包工具,到底是如何实现对https协议进行抓包的。
注意,本篇文章主要探讨的是对https协议抓包的实现原理,如果你想学习的是抓包工具的使用方法,可以参考上一篇文章 在Android手机上对https请求进行抓包 。
另外,想要理解对https协议抓包的实现原理,你还必须非常熟悉https的工作机制才行,我在 写一篇最好懂的https讲解 这篇文章中对https的工作机制进行了详细的介绍,还不熟悉https的朋友可以先去阅读这篇文章。
好了,阅读到了这里,说明你对https已经非常熟悉了,那么你一定知道,https协议是结合了非对称加密和对称加密一起工作,从而保证数据传输的安全性的。
非对称加密用于确保客户端可以安全地获取到服务器的真实公钥。对称加密用于确保客户端和服务器之间的数据传输不会被任何人监听和解密,因为对称加密使用的密钥只有客户端和服务器这两者知道,其他任何人在不知道密钥的情况下都无法对传输数据进行解密。
那么看似固若金汤的https协议,抓包工具是如何在这其中找到一个“破绽”,从而实现对https请求进行抓包的呢?
其实严格来说,这也算不上是一个破绽,而是用户的一个主动行为。还记得我们在上篇文章中讲到的,如果想要对https请求进行抓包,必须在手机上安装一个由Fiddler提供的证书吗?这个证书就是整个工作原理的核心,如果没有它,那么https就是不可能被抓包的。而安装证书需要由用户主动去操作,说明用户知道自己在干什么,自然也应该承担相应的风险。这也是为什么我一直在说,https是非常安全的,但https也是可以被抓包的,它们两者之间并不冲突。
接下来,我们就具体研究一下,为什么只需要额外安装一个证书,抓包工具就可以实现对https请求进行抓包。
我们将实现原理分成两个部分来解析,第一部分是客户端如何安全地获取服务器的真实公钥,第二部分是客户端如何与服务器商定用于对称加密的密钥。
借助那些可信赖的CA机构,客户端是可以安全地获取到服务器的真实公钥的。
CA机构专门用于给各个服务器签发数字证书,从而保证客户端可以安全地获得服务器的公钥。
服务器的管理员可以向CA机构进行申请,将自己的公钥提交给CA机构。CA机构则会帮忙制作证书,并使用自己的私钥对其加密,然后将加密后的信息返回给服务器。
这样,当客户端想要去获取某个服务器的公钥时,服务器会将CA机构签发的那段加密信息返回。那么客户端要如何解密这段信息呢?放心,主流CA机构的公钥都是被内置到操作系统当中的,所以只要是服务器的数字证书是由正规CA机构签发的,那么就一定可以被解密成功,从而客户端也就能安全地获取到服务器的公钥了。示意图如下:
而抓包工具在这个过程中可以做什么事情呢?我们还是以Fiddler举例。Fiddler的工作是介于客户端和服务器中间的,它会先于客户端接收到服务器返回的加密数据,然后它也可以使用操作系统内置的CA公钥对这段数据解密,从而得到服务器的公钥,并先将这个公钥保存起来。
接下来,Fiddler会将解密出来的数据进行调包,将其中服务器返回的公钥替换成自己的一个公钥,然后使用自己的非对称加密私钥对数据重新加密,并将这段重新加密后的数据返回给客户端。示意图如下:
但是我们知道,用Fiddler自己的私钥加密后的数据,客户端肯定解密不出来呀,因为Fiddler的公钥并没有内置到操作系统当中,这个时候就会出现我们在上篇文章看到的错误。
那么接下来要怎么办你应该很清楚了吧?这也是为什么我们一定要在手机上安装一个Fiddler提供的证书才行,只是为了让客户端能够解密出Fiddler调包之后的数据。如下图所示:
这样客户端仍然获得了一个公钥,并且还以为这个公钥是服务器返回的,实际上这是一个被Fiddler调包之后的公钥。而服务器返回的真实公钥则被Fiddler保存了起来。
到这里为止,获取服务器公钥的流程就结束了,目前各部分的状态如下:
接下来是客户端与服务器商定对称加密密钥的过程。
由于使用什么对称加密密钥是由客户端这边来决定的,客户端可以利用随机算法在本地生成一个对称加密密钥,并用服务器返回的公钥进行加密,然后发送给服务器。由于公钥加密的数据只能用私钥解密,因此没有任何人能破解出客户端生成的对称加密密钥到底是什么。
然后服务器这边使用自己的私钥将客户端发来的数据进行解密,这样客户端和服务器就都知道对称加密的密钥是什么了,并且绝对没有第三个人能知道,这样双方之后都使用对称加密来进行通讯即可,从而保证了数据传输的安全。示意图如下:
然而现在有了Fiddler,一切就都不一样了。
客户端这边拿到的其实根本就不是服务器的公钥,而是由Fiddler调包后的公钥。所以,客户端这边生成一个对称加密密钥后,使用的也是Fiddler调包后的公钥来进行加密的,这样这段加密后的数据只有用Fiddler自己的私钥才能解开。
那么很显然,Fiddler当然是有自己的私钥的,因此它能够解密出这段数据,这样Fiddler就知道客户端生成的对称加密密钥是什么了。
接下来不要忘记,Fiddler还在之前就保存了服务器返回的真实公钥,那么现在Fiddler可以用真实的服务器公钥再次加密这段数据,然后将加密后的数据发送给服务器。
对于服务器而言,它并不知道客户端这边发生了什么事,也不知道Fiddler的存在。它只知道,用自己的私钥是可以解密出客户端发来的数据,并能从中获得对称加密的密钥。示意图如下:
到这里,对称加密密钥的商定过程也就结束了,目前各部分的状态如下:
你会发现,现在客户端、服务器、Fiddler,这三者都知道对称加密的密钥是什么。
之后客户端与服务器之间的所有通讯都会使用这个密钥加密后再进行传输,不知道密钥的人自然是无法解密出传输的内容的,但是Fiddler却知道密钥是什么,因此它可以完美监听客户端与服务器之间的通讯内容,也就实现了对https协议抓包的功能。
以上就是https协议抓包的实现原理,虽然从最后的结果看上去,Fiddler在其中各种调包替换数据,干了很多不安全的操作。但Fiddler之所以有权限这么干,还是因为我们在一开始的时候手动安装了Fiddler的证书,否则后面的流程都是走不通的。
因此,https仍然是一个非常可靠且安全的数据传输协议。另外也提醒大家,除非你确实有非常明确的需求,否则千万不要在自己的手机或电脑上安装来路不明的证书,不然你的数据安全性可能就会面临非常大的威胁。
好了,今天的文章就到这里,希望对大家都能有所帮助。如果你觉得这篇文章读起来有点吃力,可能是因为你对https协议、对称加密、非对称加密还不是那么了解。我仍然建议一定要先去阅读 写一篇最好懂的https讲解 这篇文章,然后再来阅读本文收获会更大。